﻿#include "stdafx.h"
#include "C_FieldMonitor.h"

#include "Source/SettingModule/S_SettingDataContainer.h"
#include "Source/ModelingPreModule/S_ModelingPre_InteractiveManager.h"
#include "Source/ProjectModule/File/S_TempFileManager.h"
#include "../../opencascade-7.7.1/inc/gp_Pnt.hxx"
#include "MathUtils.h"

/*
-----==========================================================-----
		类：			场监视器 数据类.h
		作者：			杨骁
		所属模块：		场监视器模块
		功能：			场监视器模块的数据类对象
-----==========================================================-----
*/
C_FieldMonitor::C_FieldMonitor() : C_UndoDataBase() {

	// > 参数
	this->m_MonitorType = 1;	// 0:E-Field  1:H-Field and Surface current  2:Farfield/RCS  3:Field source  4:monostatic RCS
	this->m_SpecType = 0;		// 0:freq  1:time
	this->m_AutoName = true;

	this->m_FreqType = 0;		// 0:Frequencies(';' separated)
	this->m_Freq = 0.0;
	this->m_Freqs.clear();

	this->m_Time_Start = 0.0;
	this->m_Time_End = 10.0;
	this->m_Time_Step = 0.5;
	this->m_Time_useEndTime = true;

	// > 【频率值】-给参数赋值（不转单位）
	this->m_Freq = S_SettingDataContainer::getInstance()->getDataFrequency().getAvgFreq();

	// > 切面片
	this->x1 = 0;
	this->y1 = 0;
	this->z1 = 0;
	this->x2 = 0;
	this->y2 = 0;
	this->z2 = 0;
	this->x3 = 0;
	this->y3 = 0;
	this->z3 = 0;
	
	
	//-----------------------------------
	//----定制项目的默认值
	#if defined(DSEMUI_Customized_LargeProject_20241205)
		//（商飞项目默认时域计算）
		this->m_SpecType = 1;
	#endif
}
C_FieldMonitor::~C_FieldMonitor() {
}


/*-------------------------------------------------
		属性 - 设置名称
*/
void C_FieldMonitor::setName(QString name) {
	this->name = name;
}
QString C_FieldMonitor::getName() {
	return this->name;
}

/*-------------------------------------------------
		参数 - 从类型字符串获取类型下标
*/
int C_FieldMonitor::getMonitorTypeFromTypeStr(const QString &typeStr){

	// 0:E-Field 1:H-Field and Surface current 2:Farfield/RCS 3:Field source 4:monostatic RCS
	if (typeStr.contains("E-Field")){
		return 0;
	}
	else if (typeStr.contains("H-Field")){
		return 1;
	}
	else if (typeStr.contains("Farfield")){
		return 2;
	}
	else{
		// 默认
		return 0;
	}
}

/*-------------------------------------------------
		参数 - 从类型字符串获取类型下标
*/
int C_FieldMonitor::getSpecTypeFromTypeStr(const QString &typeStr)
{
	if (typeStr=="frequency"){
		return 0;
	}
	else if (typeStr == "time"){
		return 1;
	}
	else if (typeStr=="static"){
		return 2;
	}
	else{
		// 默认
		return 0;
	}
}

/*-------------------------------------------------
		参数 - 设置spec类型
*/
void C_FieldMonitor::setSpecType(int spec)
{
	m_SpecType = spec;
}

/*-------------------------------------------------
		参数 - 获取spec类型
*/
int C_FieldMonitor::getSpecType()
{
	return m_SpecType;
}


/*-------------------------------------------------
		参数 - 设置监视器类型
*/
void C_FieldMonitor::setMonitorType(int type)
{
	m_MonitorType = type;
}

/*-------------------------------------------------
		参数 - 获取监视器类型
*/
int C_FieldMonitor::getMonitorType()
{
	return m_MonitorType;
}

/*-------------------------------------------------
		参数 - 设置自动名称
*/
void C_FieldMonitor::setAutoNameState(bool value)
{
	m_AutoName = value;
}

/*-------------------------------------------------
		参数 - 获取自动名称
*/
bool C_FieldMonitor::getAutoNameState()
{
	return m_AutoName;
}

/*-------------------------------------------------
		参数 - 设置频率类型
*/
void C_FieldMonitor::setFreqType(int type)
{
	m_FreqType = type;
}

/*-------------------------------------------------
		参数 - 获取频率类型
*/
int C_FieldMonitor::getFreqType()
{
	return m_FreqType;
}

/*-------------------------------------------------
		参数 - 设置频率列表
*/
void C_FieldMonitor::setFreqs(QStringList freqs)
{
	m_Freqs = freqs;
}

/*-------------------------------------------------
		参数 - 获取频率列表
*/
QStringList C_FieldMonitor::getFreqs()
{
	return m_Freqs;
}

/*-------------------------------------------------
		参数 - 设置频率
*/
void C_FieldMonitor::setFreq(double freq)
{
	m_Freq = freq;
}

/*-------------------------------------------------
		参数 - 获取频率
*/
double C_FieldMonitor::getFreq()
{
	return m_Freq;
}


/*-------------------------------------------------
		参数 - 时域 - 设置起始时间
*/
void C_FieldMonitor::setTimeStart(double data) {
	this->m_Time_Start = data;
}
double C_FieldMonitor::getTimeStart() {
	return this->m_Time_Start;
}
/*-------------------------------------------------
		参数 - 时域 - 设置终止时间
*/
void C_FieldMonitor::setTimeEnd(double data) {
	this->m_Time_End = data;
}
double C_FieldMonitor::getTimeEnd() {
	return this->m_Time_End;
}
/*-------------------------------------------------
		参数 - 时域 - 设置步长
*/
void C_FieldMonitor::setTimeStep(double data) {
	this->m_Time_Step = data;
}
double C_FieldMonitor::getTimeStep() {
	return this->m_Time_Step;
}
/*-------------------------------------------------
		参数 - 时域 - 设置使用终止时间
*/
void C_FieldMonitor::setUseEndTime(bool enabled) {
	this->m_Time_useEndTime = enabled;
}
bool C_FieldMonitor::isUseEndTime() {
	return this->m_Time_useEndTime;
}



/*-------------------------------------------------
		RCS - 设置Theta
*/
void C_FieldMonitor::setTheta(double value){
	m_Theta = value;
}
double C_FieldMonitor::getTheta(){
	return m_Theta;
}

/*-------------------------------------------------
		RCS - 设置Phi
*/
void C_FieldMonitor::setPhi(double value){
	m_Phi = value;
}
double C_FieldMonitor::getPhi(){
	return m_Phi;
}

/*-------------------------------------------------
		参数 - 获取监视器类型的字符串
*/
QString C_FieldMonitor::getMonitorTypeString() {
	switch (this->m_MonitorType) {
	case 0:
		return "e-field";
	case 1:
		return "surfacecurrent";
	case 2:
		return "farfield";
	case 3:
		return "field-source";
	case 4:
		return "monostatic";
	default:
		return "e-field";
	}
}

/*-------------------------------------------------
		切面片 - 三点是否共线
*/
bool C_FieldMonitor::isCollinear() {
	return this->util_isCollinear(DSEM::Point3D(this->x1, this->y1, this->z1), DSEM::Point3D(this->x2, this->y2, this->z2), DSEM::Point3D(this->x3, this->y3, this->z3));
}
/*-------------------------------------------------
		切面片 - 根据三点算出第四个点
*/
DSEM::Point3D C_FieldMonitor::getQuadrilateralVertex() {
	return this->util_getQuadrilateralVertex(DSEM::Point3D(this->x1, this->y1, this->z1), DSEM::Point3D(this->x2, this->y2, this->z2), DSEM::Point3D(this->x3, this->y3, this->z3));
}
/*-------------------------------------------------
		切面片 - 三点是否共线
*/
bool C_FieldMonitor::util_isCollinear(const DSEM::Point3D& p1, const DSEM::Point3D& p2, const DSEM::Point3D& p3) {
	return DSEM::MathUtils::IsPointsCollinear(p1,p2,p3, DSEM::Precision::Confusion());
}
/*-------------------------------------------------
		切面片 - 根据三点算出第四个点
*/
DSEM::Point3D C_FieldMonitor::util_getQuadrilateralVertex(const DSEM::Point3D& p1, const DSEM::Point3D& p2, const DSEM::Point3D& p3) {
	return DSEM::MathUtils::GetLastQuadrilateralVertex(p1, p2, p3);
}



/*-------------------------------------------------
		描述 - 获取属性描述
*/
QPair<QString, QString> C_FieldMonitor::getAttributesDesc() {
	QPair<QString, QString> context_pair;

	context_pair.first.append(QObject::tr("Type"));
	context_pair.first.append("\n");
	context_pair.second.append("= ");
	context_pair.second.append(this->getMonitorTypeString());
	context_pair.second.append("\n");

	if (this->m_SpecType == 0) {
		context_pair.first.append(QObject::tr("Frequency"));
		context_pair.first.append("\n");
		context_pair.second.append("= ");
		context_pair.second.append(QString::number(this->m_Freq));
		context_pair.second.append(" ");
		context_pair.second.append(S_SettingDataContainer::getInstance()->getDataUnits().getCurrentString_frequency());
		context_pair.second.append("\n");

	}else if(this->m_SpecType == 1) {
		context_pair.first.append(QObject::tr("Interval"));
		context_pair.first.append("\n");
		context_pair.second.append("= ");
		context_pair.second.append(QString::number(this->m_Time_Start));
		context_pair.second.append(" ");
		context_pair.second.append(QObject::tr("to"));
		context_pair.second.append(" ");
		if (this->m_Time_useEndTime == true) {
			context_pair.second.append(QString::number(this->m_Time_End));
		}else{
			context_pair.second.append(QObject::tr("End"));
		}
		context_pair.second.append(" ");
		context_pair.second.append(S_SettingDataContainer::getInstance()->getDataUnits().getCurrentString_time());
		context_pair.second.append("\n");

		context_pair.first.append(QObject::tr("Step width"));
		context_pair.first.append("\n");
		context_pair.second.append("= ");
		context_pair.second.append(QString::number(this->m_Time_Step));
		context_pair.second.append(" ");
		context_pair.second.append(S_SettingDataContainer::getInstance()->getDataUnits().getCurrentString_time());
		context_pair.second.append("\n");
	}

	return context_pair;
}

/*-------------------------------------------------
		表面电流 - 获取网格文件
*/
bool C_FieldMonitor::genSurfaceCurrentMeshFile()
{
	QString content = S_ModelingPre_InteractiveManager::getInstance()->availableModel_getTriangleFileContext();

	// todo 暂定放在temp下，名称为test.txt
	QString filePath = QDir(S_TempFileManager::getInstance()->getTempFileUrl()).filePath("test.txt");
	QFile file(filePath);

	// 打开文件，若文件不存在则创建，若已存在则覆盖
	if (!file.open(QIODevice::WriteOnly | QIODevice::Text)){
		qDebug() << "here 无法打开文件:" << filePath;
		return false;
	}

	QTextStream out(&file);
	out << content;
	file.close();

	return true;
}

/*-------------------------------------------------
		下拉框参数 - 获取频率
*/
QStringList C_FieldMonitor::getFieldItems()
{
	QStringList fields;
	fields << QObject::tr("Frequencies(';' separated)");
	return fields;
}

/*-------------------------------------------------
		访问器 - 获取子类类名
*/
QString C_FieldMonitor::get__CLASS_NAME__() {
	return "C_FieldMonitor";
}
/*-------------------------------------------------
		访问器 - 获取子类类名（中文名）
*/
QString C_FieldMonitor::get__CLASS_NAME__Chinese() {
	return "场监视器";
}
/*-------------------------------------------------
		访问器 - 获取所有继承的类名
*/
QStringList C_FieldMonitor::get__CLASS_INHERITED_LIST__(){
	return C_UndoDataBase::get__CLASS_INHERITED_LIST__() << "C_FieldMonitor";
}
/*-------------------------------------------------
		访问器 - 是否继承了某类
*/
bool C_FieldMonitor::get__CLASS_IS_INSTANCE_OF__(QString class_name){
	return this->get__CLASS_INHERITED_LIST__().contains(class_name);
}

/*-------------------------------------------------
		访问器 - 原型复制对象
*/
C_FieldMonitor C_FieldMonitor::clone() {
	return C_FieldMonitor(*this);
}
QSharedPointer<C_FieldMonitor> C_FieldMonitor::clonePtr() {
	return QSharedPointer<C_FieldMonitor>(new C_FieldMonitor(*this));
}
C_UndoDataBasePtr C_FieldMonitor::cloneParentPtr() {
	return this->clonePtr();
}

/*-------------------------------------------------
		运算符重载
*/
const bool C_FieldMonitor::operator== (const C_FieldMonitor& a)const {
	return C_UndoDataBase::operator==(a);
}
/*-------------------------------------------------
		空判断
*/
bool C_FieldMonitor::isNull() {
	return C_UndoDataBase::isNull();
}
/*-------------------------------------------------
		实体类 -> QJsonObject
*/
QJsonObject C_FieldMonitor::getJsonObject_undoChildData() {
	QJsonObject obj;

	// > 属性
	obj.insert("name", this->name);

	// > 参数
	obj.insert("monitorType", this->m_MonitorType);
	obj.insert("auto", this->m_AutoName);
	obj.insert("specType", this->m_SpecType);
	obj.insert("freqType", this->m_FreqType);
	obj.insert("freq", this->m_Freq);
	obj.insert("Time_Start", this->m_Time_Start);
	obj.insert("Time_End", this->m_Time_End);
	obj.insert("Time_Step", this->m_Time_Step);
	obj.insert("Time_useEndTime", this->m_Time_useEndTime);

	// > RCS
	obj.insert("theta", this->m_Theta);
	obj.insert("phi", this->m_Phi);

	// > 切面片
	obj.insert("x1", this->x1);
	obj.insert("y1", this->y1);
	obj.insert("z1", this->z1);
	obj.insert("x2", this->x2);
	obj.insert("y2", this->y2);
	obj.insert("z2", this->z2);
	obj.insert("x3", this->x3);
	obj.insert("y3", this->y3);
	obj.insert("z3", this->z3);

	return obj;
}

/*-------------------------------------------------
		QJsonObject -> 实体类
*/
void C_FieldMonitor::setJsonObject_undoChildData(QJsonObject obj) {

	// > 属性
	this->name = obj.value("name").toString();

	// > 参数
	this->m_MonitorType = obj.value("monitorType").toInt();
	this->m_AutoName = obj.value("auto").toBool();
	this->m_SpecType = obj.value("specType").toInt();
	this->m_FreqType = obj.value("freqType").toInt();
	this->m_Freq = obj.value("freq").toDouble();
	this->m_Time_Start = obj.value("Time_Start").toDouble();
	this->m_Time_End = obj.value("Time_End").toDouble();
	this->m_Time_Step = obj.value("Time_Step").toDouble();
	this->m_Time_useEndTime = obj.value("Time_useEndTime").toBool(true);

	// > RCS
	this->m_Theta = obj.value("theta").toDouble();
	this->m_Phi = obj.value("phi").toDouble();

	// > 切面片
	this->x1 = obj.value("x1").toDouble();
	this->y1 = obj.value("y1").toDouble();
	this->z1 = obj.value("z1").toDouble();
	this->x2 = obj.value("x2").toDouble();
	this->y2 = obj.value("y2").toDouble();
	this->z2 = obj.value("z2").toDouble();
	this->x3 = obj.value("x3").toDouble();
	this->y3 = obj.value("y3").toDouble();
	this->z3 = obj.value("z3").toDouble();
}

